//
// Created by tcj on 2022/7/14.
//

#ifndef WEB_TEST_TIMER_H
#define WEB_TEST_TIMER_H

#include "queue"
#include "deque"
#include "ctime"
#include "chrono"
#include "unordered_map"
#include "functional"
#include "memory"
#include "assert.h"

typedef std::function<void()> TimeoutCallBack;
// high_resolution_clock（高精度时钟）
typedef std::chrono::high_resolution_clock Clock;
typedef std::chrono::milliseconds  Ms;
// ime_point：表示时间点，用来获取从纪元开始所经过的duration和当前时间，可以做一些时间的比较和算术运算
typedef Clock::time_point TimeStamp;

namespace tcj{
    class TimeNode{
    public:
        int id;                // 标记定时器
        TimeStamp expire;      // 设置过期时间
        TimeoutCallBack cb;    // 设置一个回调函数用来方便删除定时器对应的http链接

        // 定时器的比较
        bool operator<(const TimeNode& t){
            return expire<t.expire;
        }
    };

    class TimerManager{
        typedef std::shared_ptr<TimeNode> SP_TimeNode;
    public:
        TimerManager(){time_array_.reserve(64);}
        ~TimerManager(){clear();}

        void addTimer(int id, int timtout,const TimeoutCallBack &cb);   // 添加一个定时器
        void handle_expired_event();                                // 处理过期的定时器时间
        int getNextHandle();                                        // 下一次处理过期的定时器时间

        void update(int id,int timeout);                            // 更新
        void work(int id);                                          // 删除指定id结点，并用指针触发处理函数

        void pop();
        void clear();
    private:
        void del(size_t index);                     // 删除指定定时器
        void siftup(size_t i);                 // 向上调整
        bool sifydown(size_t index,size_t n);  // 向下调整
        void swapNode(size_t i,size_t j);      // 交换两个结点位置

        std::vector<TimeNode> time_array_;          // 定时器的一个数组---是一个堆结构  小根堆
        std::unordered_map<int,size_t> fd_pos_array_;    // 映射一个fd对应定时器在time_array_的位置；

    };
}

#endif //WEB_TEST_TIMER_H
